/*
 * =====================================================================================
 *
 *       Filename:  pageInfoGetter.hpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2009-2-26 10:39:57
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Fang Dongheng (fndisme), fndisme@163.com
 *        Company:  Artcoding, Shanghai, China
 *
 * =====================================================================================
 */

#ifndef FND_GAME_PAGE_INFO_GETTER_H_
#define FND_GAME_PAGE_INFO_GETTER_H_
#include <map>
#include <set>
#include <string>
#include "propertyMap.hpp"
#include <boost/noncopyable.hpp>
#include <boost/filesystem.hpp>
#include <ctime>
struct sqlite3 ;
namespace Utility {
    class page_info_getter : boost::noncopyable {
    
        typedef page_info_getter class_type ;
        typedef property_map value_type ;
        typedef std::set<std::string> string_set_type ;
    public :
        bool has_page(const std::string& page_name) const ;
        bool create_db_from_directory(const char* dir, const char* dbname) ;
        bool update_db_from_directory(const char* dir) ;
        template<typename T>
        T get(const std::string& page, const std::string& group, const
              std::string& key,
              const T& default_value = T()) {
            return get_value<T>(page_map[page], group.c_str(), key.c_str(), default_value) ;
        }
        bool get_keys(const std::string& page, property_keys_type& keys) ;
        bool get_keys(const std::string& page, const std::string& group,
                      property_keys_type& keys) ;
        
        template<typename T>
        void change(const std::string& page,
                    const std::string& group,
                    const std::string& key,
                    const T& value) {
            change_value(page_map[page], group, key, value) ;
        }

    private:
        typedef std::map<std::string, property_map> page_map_type ;
        page_map_type page_map ;
        string_set_type m_page_names ;
        const std::string cs_extend ;

    private:
        bool update_info(sqlite3* db, const std::string& key, const std::string& info) ;
        void update_child_path(const boost::filesystem::path&, sqlite3*, std::time_t, bool) ;
        
    private:
        void add_page(const char* page_file_name, const char* page_name) {
            page_map[page_name] = create_property_map_from_file(page_file_name) ;
        }
        void add_page(const std::string& page_file_name,
                      const std::string& page_name) {
            add_page(page_file_name.c_str(), page_name.c_str()) ;
        }
    public:
        void add_pages_from_db(const char* db_name) ;
        void add_pages_from_db(const std::string& db_name) {
            add_pages_from_db(db_name.c_str()) ;
        }


        void add_page_from_string(const std::string& info,
                                  const char* page_name) {
            page_map[page_name] = create_property_map_from_string(info) ;
        }
     
        bool write_page_info_to_file(const std::string& filename,
                                     const std::string& page) ;
        bool update_db(const std::string& page, const char* db_name) ;
     
    private:
        page_info_getter() : cs_extend(".txt") {}
    public:
        static page_info_getter& Instance() ;
    } ;

    template<typename T>
    std::string to_string(const T& obj) {
        try {
            return boost::lexical_cast<std::string>(obj) ;
        } catch(boost::bad_lexical_cast& e) {
            return "" ;
        }
    }
}

#endif 

